package de.dhbw.horb.inf2013.vierFarbenProblem.viewModel.lineToFigure;

/**
 * The Class Line (not working).
 */
public class Line {
	
	
	/** The from. */
	private Point from;
	
	/** The to. */
	private Point to;

	/**
	 * Instantiates a new line.
	 *
	 * @param from the from
	 * @param to the to
	 */
	public Line(Point from, Point to){
		this.from = from;
		this.to = to;
	}
	
	/**
	 * Gets the gradient.
	 *
	 * @return the gradient
	 */
	public double getGradient(){
		return (to.getY()-from.getY())/(to.getX()-from.getX());
	}
	
	/**
	 * Gets the y intercept.
	 *
	 * @return the y intercept
	 */
	public double getYIntercept(){
		return from.getY()-getGradient()*from.getX();
	}
	
	/**
	 * Gets the x on line.
	 *
	 * @param y the y
	 * @return the x on line
	 */
	public double getXOnLine(int y){
		return ((y-getYIntercept())/getGradient());
	}
	
	/**
	 * Gets the y on line.
	 *
	 * @param x the x
	 * @return the y on line
	 */
	public double getYOnLine(int x){
		return getGradient()*x+getYIntercept();
	}
	
	/**
	 * Gets the intersection.
	 *
	 * @param l1 the l1
	 * @param l2 the l2
	 * @return the intersection
	 * @throws NoIntersectionPointExistsException the no intersection point exists exception
	 */
	public static Point getIntersection(Line l1, Line l2) throws NoIntersectionPointExistsException{
		int x;
		double y;
		//TODO parales lines + point between line points
		if(l1.getFrom().getX() == l1.getTo().getX() && l1.getFrom().getX() == l2.getFrom().getX()){
			throw new NoIntersectionPointExistsException();
		}else if(l1.getFrom().getX() == l1.getTo().getX()){
			x = l1.getFrom().getX();
			y = l2.getYOnLine(x);
		}else if(l2.getFrom().getX() == l2.getTo().getX()){
			x = l2.getFrom().getX();
			y = l1.getYOnLine(x);
		}else if(l1.getGradient() == l2.getGradient()){
			throw new NoIntersectionPointExistsException();
		}else{
			x = (int) ((l2.getYIntercept()-l1.getYIntercept())/(l1.getGradient()-l2.getGradient()));
			y = l1.getYOnLine(x);
		}
		Point p = new Point(x, (int) y);
		if(l1.isPointOnLine(p) && l2.isPointOnLine(p)){
			return p;
		}
		
		
		throw new NoIntersectionPointExistsException();
	}
	
	/**
	 * Gets the from.
	 *
	 * @return the from
	 */
	public Point getFrom(){
		return from;
	}
	
	/**
	 * Gets the to.
	 *
	 * @return the to
	 */
	public Point getTo(){
		return to;
	}
	
	/**
	 * Checks if is point on line.
	 *
	 * @param p the p
	 * @return true, if is point on line
	 */
	public boolean isPointOnLine(Point p){
		//TODO Checks only if the point is between from and to
		
		int maxX = Math.max(this.getFrom().getX(), this.getTo().getX());
		int minX = Math.min(this.getFrom().getX(), this.getTo().getX());
		
		int maxY = Math.max(this.getFrom().getY(), this.getTo().getY());
		int minY = Math.min(this.getFrom().getY(), this.getTo().getY());

		if(p.getX() <= maxX && p.getX() >= minX && p.getY() <= maxY && p.getY() >= minY){
			return true;
		}
		
		return false;
	}
	
	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	public boolean equals(Object obj){
		Line line = (Line) obj;
		boolean result = false;
		
		if((line.getFrom().equals(getFrom()) && line.getTo().equals(getTo()))
				|| (line.getFrom().equals(getTo()) && line.getTo().equals(getFrom()))){
			result = true;
		}
		
		return result;
	}
}
